package com.example.demo.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.example.demo.common.constant.CacheConstants;
import com.example.demo.mapper.SysDictMapper;
import com.example.demo.model.converter.SysDictItemConverter;
import com.example.demo.model.core.PageVo;
import com.example.demo.model.entity.SysDict;
import com.example.demo.model.form.DictForm;
import com.example.demo.model.form.DictItemForm;
import com.example.demo.model.form.DictItemSaveForm;
import com.example.demo.model.query.DictItemQuery;
import com.example.demo.model.query.DictQuery;
import com.example.demo.model.vo.DictItemVO;
import com.example.demo.model.vo.DictVO;
import com.example.demo.model.vo.OptionVO;
import com.example.demo.service.CacheableAsyncAbstractService;
import com.example.demo.service.CacheableInitService;
import com.example.demo.service.SysDictService;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

@Service
@Primary
public class SysDictServiceCacheImpl extends CacheableAsyncAbstractService implements SysDictService, CacheableInitService {

    @Autowired
    @Qualifier("sysDictServiceImpl")
    private SysDictService service;
    @Autowired
    private CacheManager cacheManager;
    @Autowired
    private SysDictItemConverter converter;
    @Autowired
    private SysDictMapper sysDictMapper;


    @Override
    public void add(DictForm dictForm) {
        service.add(dictForm);
    }

    @Override
    public void update(DictForm dictForm) {
        service.update(dictForm);
    }

    @Override
    public void delete(List<Long> ids) {
        List<SysDict> sysDicts = sysDictMapper.selectListByIds(ids);
        for (SysDict sysDict : sysDicts) {
            deleteCache(sysDict.getDictCode());
            scheduleCacheOperation(() -> deleteCache(sysDict.getDictCode()));
        }
        service.delete(ids);
    }

    @Override
    public PageVo<DictVO> page(DictQuery query) {
        return service.page(query);
    }

    @Override
    public DictForm form(Long id) {
        return service.form(id);
    }

    @Override
    public void addItem(DictItemForm form) {
        service.addItem(form);
    }

    @Override
    public void updateItem(DictItemForm form) {
        service.updateItem(form);
    }

    @Override
    public void deleteItem(List<Long> ids) {
        service.deleteItem(ids);
    }

    @Override
    public PageVo<DictItemVO> pageItem(DictItemQuery query) {
        return service.pageItem(query);
    }

    @Override
    public DictItemForm formItem(Long id) {
        return service.formItem(id);
    }

    @Override
    public void itemsSave(DictItemSaveForm form) {
        service.itemsSave(form);
        insertCache(form.getDictCode(), converter.formToVoList(form.getItems()));
    }

    @Override
    public List<OptionVO<String>> itemsOption(String dictCode) {
        return service.itemsOption(dictCode);
    }

    @Override
    public List<DictItemVO> listDictItem(String dictCode) {
        List<DictItemVO> list =  getCache(dictCode);
        if(list != null) {
            return list;
        }
        list = service.listDictItem(dictCode);
        if(list != null) {
            insertCache(dictCode, list);
        }
        return list;
    }

    @Override
    public DictItemVO getDictItem(String dictCode, String itemCode) {
        return service.getDictItem(dictCode, itemCode);
    }


    @Override
    @PostConstruct
    public void initCache() {
        List<SysDict> sysDictList = sysDictMapper.selectListByQuery(QueryWrapper.create());
        for (SysDict sysDict : sysDictList) {
            List<DictItemVO> dictItemVOS = service.listDictItem(sysDict.getDictCode());
            if(CollectionUtil.isNotEmpty(dictItemVOS)) {
                insertCache(sysDict.getDictCode(), dictItemVOS);
            }
        }
    }

    private void deleteCache(String dictCode) {
        Objects.requireNonNull(cacheManager.getCache(CacheConstants.CacheName.SYSTEM)).evictIfPresent(CacheConstants.CacheKey.DICTITEM + dictCode);

    }
    private void insertCache(String dictCode, List<DictItemVO> list) {
        Objects.requireNonNull(cacheManager.getCache(CacheConstants.CacheName.SYSTEM)).put(CacheConstants.CacheKey.DICTITEM + dictCode, list);
    }
    private List<DictItemVO> getCache(String dictCode) {
        return Objects.requireNonNull(cacheManager.getCache(CacheConstants.CacheName.SYSTEM)).get(CacheConstants.CacheKey.DICTITEM + dictCode,List.class);
    }

}
